package com.bitspilani.infonet;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.Vibrator;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
import android.view.Menu;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.bitspilani.infonet.bo.RiskResponse;
import com.bitspilani.infonet.constants.GlobalConstants;
import com.bitspilani.infonet.core.AccelerometerHandler;
import com.bitspilani.infonet.core.GyroscopeHandler;
import com.bitspilani.infonet.core.RiskSpeedListner;

public class MainActivity extends Activity{
	private static TextView accMeter;
	private static TextView accMeterLabel;
	private static TextView gyroRate;
	private static TextView gyroReading;
	private static TextView patchDetails;
	private static ProgressBar spinner;
	private static SensorManager mSensorManager;
	private static Sensor mAccSensor;
	private static Sensor mGravitySensor;
	private static Sensor mGyroSensor;
	private static AccelerometerHandler accHandler = new AccelerometerHandler();
	private static GyroscopeHandler gyroHandler = new GyroscopeHandler();
	private static RelativeLayout activityLayout;
	private static Context activityContext;
	private static Vibrator vibrator;
	private static int cnt=0;
	private PowerManager.WakeLock wl;
	private  LocationListener mlocListener;
	private static LocationManager mlocManager;
	private static RiskSpeedListner riskSpeedListner = new RiskSpeedListner();
	public static MainActivity mainActivityRef;
	/**
	 * @return the mlocManager
	 */
	public static LocationManager getMlocManager() {
		return mlocManager;
	}



	/**
	 * @param mlocManager the mlocManager to set
	 */
	public static void setMlocManager(LocationManager mlocMgr) {
		mlocManager = mlocMgr;
	}



	public MainActivity(){

	}



	@Override
	protected void onCreate(Bundle savedInstanceState) {
		mainActivityRef = this;
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		activityContext = getApplicationContext();
		vibrator = (Vibrator) getSystemService(activityContext.VIBRATOR_SERVICE);
		//playNotificationSound();

		  PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
          wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,"tag");
          wl.acquire();

		activityLayout =(RelativeLayout)findViewById(R.id.activityLayout);

		System.out.println("On create fired");

		accMeter = (TextView) findViewById(R.id.accMeter);
		accMeterLabel = (TextView) findViewById(R.id.accMeterLabel);
		gyroRate = (TextView) findViewById(R.id.gyroRate);
		gyroReading = (TextView) findViewById(R.id.gyroReading);
		spinner = (ProgressBar)findViewById(R.id.spinner);
		mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		mAccSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);//liner acc=acc-gravity's effect
		mGyroSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
		//mGravitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);

		mSensorManager.registerListener(accHandler, mAccSensor, SensorManager.SENSOR_DELAY_NORMAL);
		mSensorManager.registerListener(gyroHandler, mGyroSensor, SensorManager.SENSOR_DELAY_NORMAL);
		//mSensorManager.registerListener(accHandler, mGravitySensor, SensorManager.SENSOR_DELAY_NORMAL);

		

		/**GPS location code**/
		mlocManager= (LocationManager) getSystemService(LOCATION_SERVICE);
		System.out.println("mlocManager: "+mlocManager);
		boolean enabled = mlocManager
		  .isProviderEnabled(LocationManager.GPS_PROVIDER);

		// check if enabled and if not send user to the GSP settings
		// Better solution would be to display a dialog and suggesting to 
		// go to the settings
		if (!enabled) {
			Toast.makeText(this, "Please enable GPS.",
	                Toast.LENGTH_SHORT).show();

		  Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
		  startActivity(intent);
		  
		} 
		
		
		
		gyroHandler.scheduleGyroTimer();
		riskSpeedListner.scheduleRiskAndSpeedListning();
	
	}
	
	public  void showSpinner(){
		runOnUiThread(new Runnable() {

			@Override
			public void run() {
				spinner.setVisibility(View.VISIBLE);
				
			}
		});
	}
	
	public  void hideSpinnerAndShowToast(final String msg, final int length){
		runOnUiThread(new Runnable() {

			@Override
			public void run() {
				spinner.setVisibility(View.INVISIBLE);
				Toast.makeText(mainActivityRef, msg,
		                length).show();
				
			}
		});
		
	}
	public  void showOverSpeedingNotification(final float speedLimit, final float currentSpeed){
		runOnUiThread(new Runnable() {

			@Override
			public void run() {
				NotificationCompat.Builder mBuilder =
				        new NotificationCompat.Builder(mainActivityRef)
				        .setSmallIcon(R.drawable.ubiicon)
				        .setContentTitle("Over Speeding Alert")
				        .setContentText("You are travelling at: "+currentSpeed+" KMPH which exceeds the speed limit of: "+speedLimit+" KMPH!");
				// Creates an explicit intent for an Activity in your app
				Intent resultIntent = new Intent(mainActivityRef, MainActivity.class);

				// The stack builder object will contain an artificial back stack for the
				// started Activity.
				// This ensures that navigating backward from the Activity leads out of
				// your application to the Home screen.
				TaskStackBuilder stackBuilder = TaskStackBuilder.create(mainActivityRef);
				// Adds the back stack for the Intent (but not the Intent itself)
				stackBuilder.addParentStack(MainActivity.class);
				// Adds the Intent that starts the Activity to the top of the stack
				stackBuilder.addNextIntent(resultIntent);
				PendingIntent resultPendingIntent =
				        stackBuilder.getPendingIntent(
				            0,
				            PendingIntent.FLAG_UPDATE_CURRENT
				        );
				mBuilder.setContentIntent(resultPendingIntent);
				NotificationManager mNotificationManager =
				    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
				// mId allows you to update the notification later on.
				int mId = 1;
				mNotificationManager.notify(mId, mBuilder.build());
				
			}
		});
		
	}
	
	public  void showRiskNotification(final RiskResponse riskResponse){
		runOnUiThread(new Runnable() {

			@Override
			public void run() {
				NotificationCompat.Builder mBuilder =
				        new NotificationCompat.Builder(mainActivityRef)
				        .setSmallIcon(R.drawable.ubiicon)
				        .setContentTitle("Risk Found "+riskResponse.getRiskDistance() * 1000+" Meters Away")
				        .setContentText("Distance: "+riskResponse.getRiskDistance() * 1000+" m, " +
				        		"Coordinates: ("+riskResponse.getRiskLocation().getLattitide()+", " +
				        				riskResponse.getRiskLocation().getLongitude()+")");
				// Creates an explicit intent for an Activity in your app
				Intent resultIntent = new Intent(mainActivityRef, MainActivity.class);

				// The stack builder object will contain an artificial back stack for the
				// started Activity.
				// This ensures that navigating backward from the Activity leads out of
				// your application to the Home screen.
				TaskStackBuilder stackBuilder = TaskStackBuilder.create(mainActivityRef);
				// Adds the back stack for the Intent (but not the Intent itself)
				stackBuilder.addParentStack(MainActivity.class);
				// Adds the Intent that starts the Activity to the top of the stack
				stackBuilder.addNextIntent(resultIntent);
				PendingIntent resultPendingIntent =
				        stackBuilder.getPendingIntent(
				            0,
				            PendingIntent.FLAG_UPDATE_CURRENT
				        );
				mBuilder.setContentIntent(resultPendingIntent);
				NotificationManager mNotificationManager =
				    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
				// mId allows you to update the notification later on.
				int mId = 1;
				mNotificationManager.notify(mId, mBuilder.build());
				
			}
		});
		
	}
	
	public static void showToast(String msg, int length){
		Toast.makeText(mainActivityRef, msg,
                length).show();
	}
	
	public static void vibrate(){
		vibrator.vibrate(GlobalConstants.VIBRATION_LENGTH);
	}

	public static void setAccTextViews(String text){
		if(! text.contains("PANIC BRAKED")){
			accMeter.setText(text);
			++cnt;
			if(cnt==1){
				accMeterLabel.setText("Monitoring Accelerometer .");
			}else if(cnt==2){
				accMeterLabel.setText("Monitoring Accelerometer ..");
			}else if(cnt==3){
				accMeterLabel.setText("Monitoring Accelerometer ...");
				cnt=0;
			}
		}else{
			accMeterLabel.setText("PANIC BRAKED");
			accMeter.setText(text);
		}


	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}


	protected void onResume() {
		super.onResume();
		resumeListners();
		 wl.acquire();
	//	mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
	        //Register for location updates using a Criteria and pending intent.
	}

	protected void onPause() {
		super.onPause();
		pauseListners();
		wl.release();
		//mlocManager.removeUpdates(mlocListener);
	}

	private static void resumeListners(){
		mSensorManager.registerListener(accHandler, mAccSensor, SensorManager.SENSOR_DELAY_NORMAL);
		//mSensorManager.registerListener(accHandler, mGravitySensor, SensorManager.SENSOR_DELAY_NORMAL);
		mSensorManager.registerListener(gyroHandler, mGyroSensor, SensorManager.SENSOR_DELAY_NORMAL);

	}
	private static void pauseListners(){
		mSensorManager.unregisterListener(accHandler);//pause accelerometer and gravity sensors
		mSensorManager.unregisterListener(gyroHandler);//pause gyro sensors
		
	}

	public  void updateGyro(final String gyroRatei, final String gyroReadings){
		runOnUiThread(new Runnable() {

			@Override  
			public void run() {  
				gyroRate .setText(gyroRatei);
				gyroReading.setText(gyroReadings);
			}  
		}); 
	}
	
	
	public  void relaxListning(){

		pauseListners();
		System.out.println("Paused listners");
		activityLayout.setBackgroundColor(Color.RED);

		final Timer  t = new Timer();     
		TimerTask task = new TimerTask() {

			@Override  
			public void run() {  

				t.cancel();
				resumeListners();
				System.out.println("Resumed Listners");

				runOnUiThread(new Runnable() {

					@Override  
					public void run() {  
						activityLayout.setBackgroundColor(Color.WHITE);
					}  
				});  
			}  
		};  
		t.scheduleAtFixedRate(task, GlobalConstants.PAUSE_LENGTH, GlobalConstants.PAUSE_LENGTH);  
	} 

	public  void notifyPanicBraking(){

		runOnUiThread(new Runnable() {

			@Override
			public void run() {
				try {


					vibrator.vibrate(GlobalConstants.VIBRATION_LENGTH);

					Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
					if(alert == null){
						// alert is null, using backup
						alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
						if(alert == null){  // I can't see this ever being null (as always have a default notification) but just incase
							// alert backup is null, using 2nd backup
							alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);               
						}
					}
					// Context ctx = getApplicationContext();
					Ringtone r = RingtoneManager.getRingtone(activityContext, alert);
					r.play();
				} catch (Exception e) {
					e.printStackTrace();
				}

			}  });


	}

}
